// 数据库
const db = require('./../db/db');
// 日期库
const dayjs = require('dayjs');
// 工具类: jwt
const jwt = require('./../utils/jwt');
// 工具类: 快速返回值
const back = require('./../utils/back');

/**
 * token
 */
const token = {
  /**
   * 生成Token
   * @param string userType 用户类型: 管理员|用户
   * @param string userId   用户ID
   * @param string userName 用户姓名
   * @returns back
   */
  async New(userType, userId, userName) {
    const d = dayjs();
    // 生成时间
    const create_time = d.format('YYYY-MM-DD HH:mm:ss');
    // 过期时间
    const lose_time = d
      .add(60 * 60 * 12 - 10, 'second')
      .format('YYYY-MM-DD HH:mm:ss');

    // 生成Token
    const code = jwt.sign({
      user_type: userType,
      user_id: userId,
      user_name: userName,
    });

    // 写入数据库
    let state = await db.query(
      `insert into tokens(state,user_type,user_id,user_name,token,create_time,lose_time) values(1,?,?,?,?,?,?)`,
      [userType, userId, userName, code, create_time, lose_time]
    );
    if (state === false) {
      return back.ERR(back.ERRTYPE.ERROR_DB, 'Token记录写入失败');
    }

    // 更新其他Token为过期状态
    state = await db.query(
      `update tokens set state=2 where user_type=? AND user_id=? AND token!=? AND state=1`,
      [userType, userId, code]
    );
    if (state === false) {
      return back.ERR(back.ERRTYPE.ERROR_DB, 'Token记录更新失败');
    }

    // 返回Token串
    return back.Key(code);
  },
  /**
   * 验证Token
   * @param string code     Token串
   * @returns
   */
  async Valid(code) {
    // console.log(code);
    // Token为空
    if (code == '') {
      return back.ERR(back.ERRTYPE.ERROR_TOKEN, 'Token不能为空');
    }

    // 解析Token
    const codeInfo = await jwt.parse(code);
    // console.log(codeInfo);//用了一个有效期内的token可以修改任何的user信息
    if (codeInfo === false) {
      return back.ERR(back.ERRTYPE.ERROR_TOKEN, '无效的Token');
    }

    // 检查Token状态 问题在这里 只要是有这个token就可以查到
    const tokenInfo = await db.query(
      `select id,state from tokens where token=?`,
      [code]
    );
    if (tokenInfo === false) {
      return back.ERR(back.ERRTYPE.ERROR_DB, 'Token记录查询失败');
    }
    if (tokenInfo === null) {
      return back.ERR(back.ERRTYPE.ERROR_TOKEN, '无效的Token');
    }
    if (token.state === 2) {
      return back.ERR(back.ERRTYPE.ERROR_TOKEN, '过期的token');
    }

    // 返回正常信息
    return back.Data(codeInfo);
  },
  /**
   * 过期Token
   * @param string userType 用户类型[管理员|用户]
   * @param string userId   用户ID
   */
  async Expired(userType, userId) {
    await db.query(
      `update tokens set state=2 where user_type=? AND user_id=?`,
      [userType, userId]
    );
  },
};

module.exports = token;
